﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AgileSaude.Entities;
using Uol.PagSeguro.Constants;
using Uol.PagSeguro.Domain;
using Uol.PagSeguro.Exception;
using Uol.PagSeguro.Resources;
using Uol.PagSeguro.Service;
using System.Net;

namespace AgileSaude.Business.Process
{
    internal class PagSeguroProcess
    {
        internal const string email = "vendas@agilesaude.com.br";
        internal const string token = "DC4543BC382F48CE865CDEB4FD903245";

        internal PagSeguroProcess(string pUrlXmlConfiguration)
        {
            if (pUrlXmlConfiguration != "")
                PagSeguroConfiguration.urlXmlConfiguration = pUrlXmlConfiguration;
        }

        internal Uri RequisicaoPagto(PedidoEntities pPedido, ref Resultado resultado)
        {
            if (resultado == null)
                resultado = new Resultado();

            // TODO: Substitute the parameters below with your credentials
            AccountCredentials credentials = new AccountCredentials(email, token);
            //AccountCredentials credentials = PagSeguroConfiguration.Credentials;

            try
            {
                // Instantiate a new payment request
                PaymentRequest payment = new PaymentRequest();

                // Sets the currency
                payment.Currency = Currency.Brl;

                // Add an item for this payment request
                foreach(Pedido_ServicosEntities item in pPedido.Servicos)
                    payment.Items.Add(new Item(item.Item.ToString(), item.ServicoNome, 1, item.Valor));
               
                // Sets a reference code for this payment request, it is useful to identify this payment in future notifications.
                payment.Reference = pPedido.Numero;

                // Sets shipping information for this payment request
                payment.Shipping = new Shipping();
                payment.Shipping.ShippingType = ShippingType.Sedex;

                //Passando valor para ShippingCost
                payment.Shipping.Cost = 0.00m;

                payment.Shipping.Address = new Address(
                    "BRA",
                    pPedido.Usuario.UF.ToUpper(),
                    pPedido.Usuario.CidadeNome,
                    pPedido.Usuario.Bairro,
                    pPedido.Usuario.CEP.Replace("-",""),
                    pPedido.Usuario.Endereco,
                    pPedido.Usuario.Numero,
                    pPedido.Usuario.Complemento
                );

                // Sets your customer information.
                payment.Sender = new Sender(
                    pPedido.Usuario.Nome,
                    pPedido.Usuario.Email,
                    new Phone(pPedido.Usuario.DDDResidencial, pPedido.Usuario.TelResidencial.Replace("-", ""))
                );

                // Sets the url used by PagSeguro for redirect user after ends checkout process
                payment.RedirectUri = new Uri("http://www.agilesaude.com.br");

                // Add checkout metadata information
                //payment.AddMetaData(MetaDataItemKeys.GetItemKeyByDescription("CPF do passageiro"), "123.456.789-09", 1);
                //payment.AddMetaData("PASSENGER_PASSPORT", "23456", 1);

                // Another way to set checkout parameters
                //payment.AddParameter("senderBirthday", "07/05/1980");
                //payment.AddIndexedParameter("itemColor", "verde", 1);
                //payment.AddIndexedParameter("itemId", "0003", 3);
                //payment.AddIndexedParameter("itemDescription", "Mouse", 3);
                //payment.AddIndexedParameter("itemQuantity", "1", 3);
                //payment.AddIndexedParameter("itemAmount", "200.00", 3);

                SenderDocument senderCPF = new SenderDocument(Documents.GetDocumentByType("CPF"), pPedido.Usuario.CPF);
                payment.Sender.Documents.Add(senderCPF);

                Uri paymentRedirectUri = payment.Register(credentials);

                return paymentRedirectUri;

                //Console.WriteLine("URL do pagamento : " + paymentRedirectUri);
                //Console.ReadKey();
            }
            catch (PagSeguroServiceException exception)
            {
                if (exception.StatusCode == HttpStatusCode.Unauthorized)
                {
                    //Console.WriteLine("Unauthorized: please verify if the credentials used in the web service call are correct.\n");
                }
                String mensagem = exception.Message;
                new ResultadoProcess().GravarLog(ref resultado, mensagem, "AgileSaude", "", "RequisicaoPagto", "PagSeguroProcess");
                resultado.Sucesso = false;
                throw exception;
            }
            catch (Exception ex)
            {
                String mensagem = ex.Message;
                new ResultadoProcess().GravarLog(ref resultado, mensagem, "AgileSaude", "", "RequisicaoPagto", "PagSeguroProcess");
                resultado.Sucesso = false;
                throw ex;
            }

        }

        internal Transaction ConsultaPorTransactionCode(string notificationType, string notificationCode)
        {
            Resultado resultado = new Resultado();
            Transaction transaction = null;

            try
            {
                AccountCredentials credentials = new AccountCredentials(email, token);

                if (notificationType == "transaction")
                {
                    // obtendo o objeto transaction a partir do código de notificação  
                    transaction = NotificationService.CheckTransaction(
                        credentials,
                        notificationCode
                    );
                }  

                resultado.Sucesso = true;
            }
            catch (Exception ex)
            {
                String mensagem = ex.Message;
                new ResultadoProcess().GravarLog(ref resultado, mensagem, "AgileSaude", "", "ConsultaPorTransactionCode", "PagSeguroProcess");
                resultado.Sucesso = false;
                throw ex;
            }

            return transaction;

        }

        internal TransactionSearchResult ConsultaPorData(DateTime pDtIni, DateTime pDtFim, int pPageNumber)
        {
            AccountCredentials credentials = new AccountCredentials(email, token);

            // Definindo a data de ínicio da consulta   
            DateTime initialDate = new DateTime(pDtIni.Year, pDtIni.Month, pDtIni.Day, 0, 0, 0);

            // Definindo a data de término da consulta  
            DateTime finalDate;
            if (long.Parse(pDtFim.ToString("yyyyMMdd")) >= long.Parse(DateTime.Now.ToString("yyyyMMdd")))
                finalDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute-5, DateTime.Now.Second);
            else
                finalDate = new DateTime(pDtFim.Year, pDtFim.Month, pDtFim.Day, 23, 59, 59);

            // Definindo o número máximo de resultados por página  
            int maxPageResults = 20;

            // Definindo o número da página  
            //int pageNumber = 1;

            // Realizando a consulta  
            return TransactionSearchService.SearchByDate(
                credentials,
                initialDate,
                finalDate,
                pPageNumber,
                maxPageResults
            );

       }

        internal string getTransactionCode(DateTime pDtIni, DateTime pDtFim, string pReference)
        {
            AccountCredentials credentials = new AccountCredentials(email, token);

            // Definindo o número da página  
            //int pageNumber = 1;

            // Realizando a consulta  
            TransactionSearchResult result = ConsultaPorData(pDtIni, pDtFim, 1);

            string transactioncode = "";
            foreach (TransactionSummary summary in result.Transactions)
            {
                if (summary.Reference == pReference)
                {
                    transactioncode = summary.Code;
                    break;
                }
                
            }

            return transactioncode;
        }
    }
}
